﻿using NahidaProject4CSharp.UnitTest.NahidaBenchmarkTest;
using NahidaProject4CSharp.UnitTest.NahidaMockTest;
using NahidaProject4CSharp.UnitTest.NahidaUnitTest;
using System;
using System.Reflection;
using System.Text;

namespace NahidaProject4CSharp.UnitTest.FunctionalTest {
	public class UnitTestTests{

		[Test] public void TestPoint1() {
			Assert.Equals(1 + 1, 2);
		}

		[Test] public void TestPoint2() {
			Assert.Equals(2 + 2, 22);
		}
	}

	[BenchmarkClass(Name = "TestClass1", Description = "Testing various string operations performance")]
	public class TestClass1 {
		[Benchmark(Iterations = 1000, Warmup = 10, Description = "String concatenation using + operator")]
		public void TestPoint1(){
			string result = "";
			for (int i = 0; i < 100; i++)
			{
				result += "test";
			}
		}

		[Benchmark(Iterations = 1000, Warmup = 10, Description = "String concatenation using StringBuilder")]
		public void TestPoint2(){
			var sb = new StringBuilder();
			for (int i = 0; i < 100; i++){
				sb.Append("test");
			}
			sb.ToString();
		}

		[Benchmark(Iterations = 1000, Warmup = 10, Description = "String.Join operation")]
		public void TestPoint3(){
			var array = new string[100];
			for (int i = 0; i < 100; i++){
				array[i] = "test";
			}
			string.Join("", array);
		}

		[Benchmark(Iterations = 100, Warmup = 5, Description = "Parameterized string format test")]
		public void TestPoint4([BenchmarkParam("Hello", "World", "Test")] string input){
			string.Format("Formatted: {0}", input);
		}
	}

	public interface IUserService
	{
		string GetUserName(int userId);
		int GetUserCount();
		void SaveUser(string name);
		bool DeleteUser(int userId);
	}

	public class UserServiceConsumer
	{
		private readonly IUserService _userService;

		public UserServiceConsumer(IUserService userService)
		{
			_userService = userService;
		}

		public string GetWelcomeMessage(int userId)
		{
			var userName = _userService.GetUserName(userId);
			return $"Welcome, {userName}!";
		}

		public void CreateUser(string name)
		{
			_userService.SaveUser(name);
		}

		public bool RemoveUser(int userId)
		{
			return _userService.DeleteUser(userId);
		}
	}

	internal class Program {
		static void Main() {
			var assemblyRunner = new TestRunner();
			assemblyRunner.RunTests(Assembly.GetExecutingAssembly());
			assemblyRunner.PrintResults();

			var runner = new BenchmarkRunner();

			runner.OnTestCompleted += (result) =>{
				if (result.Success){
					Console.WriteLine($"Completed: {result.TestName} - {result.AverageMs:F3}ms avg");
				}
				else{
					Console.WriteLine($"Failed: {result.TestName} - {result.Exception?.Message}");
				}
			};

			runner.OnSuiteCompleted += (suiteResult) =>{
				Console.WriteLine($"\nSuite '{suiteResult.SuiteName}' completed in {suiteResult.TotalDuration.TotalMilliseconds:F2}ms");
			};

			var stringResults = runner.Run<TestClass1>();
			BenchmarkReporter.GenerateDetailedConsoleReport(stringResults);

			var mockUserService = MockFactory.CreateMock<IUserService>();
			mockUserService.Setup(x => x.GetUserName(1), "John Doe");
			mockUserService.Setup(x => x.GetUserCount(), 5);
			mockUserService.Setup(x => x.DeleteUser(1), true);

			var consumer = new UserServiceConsumer(mockUserService.Object);

			var welcomeMessage = consumer.GetWelcomeMessage(1);
			Console.WriteLine($"Welcome Message: {welcomeMessage}");

			consumer.CreateUser("Jane Doe");

			var deleteResult = consumer.RemoveUser(1);
			Console.WriteLine($"Delete Result: {deleteResult}");

			try
			{
				mockUserService.Verify(x => x.GetUserName(1), Times.Once());
				mockUserService.Verify(x => x.SaveUser("Jane Doe"), Times.Once());
				mockUserService.Verify(x => x.DeleteUser(1), Times.Once());
				Console.WriteLine("All verifications passed!");
			}
			catch (MockException ex)
			{
				Console.WriteLine($"Verification failed: {ex.Message}");
			}

			try
			{
				mockUserService.Verify(x => x.GetUserCount(), Times.Once());
			}
			catch (MockException ex)
			{
				Console.WriteLine($"Expected verification failure: {ex.Message}");
			}
		}
	}
}
